package ws

import (
	"fmt"
	"net"
	"net/http"
	"net/url"

	"github.com/gorilla/websocket"
)
type WsServer struct {
    listener net.Listener
    addr     string
    path     string
    upgrade  *websocket.Upgrader
    handle   func(*websocket.Conn)
}

func NewWsServer(Url string) (*WsServer,error) {
    ws := new(WsServer)
    u,err := url.Parse(Url)
    if err != nil {
        return nil,fmt.Errorf("bad url %s:%v",Url,err)
    }
    ws.addr = u.Host
    ws.path = u.Path
    ws.upgrade = &websocket.Upgrader{
        ReadBufferSize:  4096,
        WriteBufferSize: 1024,
        CheckOrigin: func(r *http.Request) bool {
            if r.Method != "GET" {
                fmt.Println("method is not GET")
                return false
            }
            if r.URL.Path != u.Path {
                fmt.Println("path error")
                return false
            }
            return true
        },
    }
    return ws,nil
}

func(self *WsServer) RegistHandle(h func(*websocket.Conn)) {
    self.handle = h
}

func (self *WsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if r.URL.Path != self.path {
        httpCode := http.StatusInternalServerError
        reasePhrase := http.StatusText(httpCode)
        http.Error(w, reasePhrase, httpCode)
        fmt.Printf("path mismatch, error: %v\n", reasePhrase)
    }
    conn, err := self.upgrade.Upgrade(w, r, nil)
    if err != nil {    
        fmt.Printf("websocket error: %v\n", err)
    }
    fmt.Println("client connect :", conn.RemoteAddr())
    go self.handle(conn)
}

func (self *WsServer) Start() (err error) {
    self.listener, err = net.Listen("tcp", self.addr)
    if err != nil {
        return fmt.Errorf("net listen error: %v", err)
    }
    err = http.Serve(self.listener, self)
    if err != nil {
        return fmt.Errorf("http serve error: %v", err)
    }
    return nil
}

